﻿using Ebusiness_WebSites.Services.Dtos;
using Ebusiness_WebSites.Token;
using IdentityModel.Client;
using Microsoft.AspNetCore.Authentication;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Options;
using Volo.Abp.IdentityModel;

namespace Ebusiness_WebSites.Controllers
{
    [Route("api/[controller]/[action]")]
    [ApiController]
    public class TokenController : ControllerBase
    {
        public IIdentityModelAuthenticationService authenticationService { get; set; }

        public IHttpClientFactory _httpClientFactory { get; set; }
        public IConfiguration _configuration { get; set; }

        public IOptions<AuthserverOptions> _options { get; set; }

        [HttpPost]
        public async Task<string> CreateClientToken()
        {
            #region 客户端模式
            {
                ////1、配置权限服务信息
                //IdentityClientConfiguration idc = new IdentityClientConfiguration();
                //idc.Authority = "https://localhost:44392"; // 权限服务地址
                //idc.ClientId = "website"; //客户端Id
                //idc.ClientSecret = "123456";//客户端密码
                ////Possible values: "client_credentials" or "password". Default value: "client_credentials".
                //idc.GrantType = "client_credentials"; // 授权类型，给客户端授权  
                //idc.Scope = "address OrderService"; // 电商网站可以访问那些微服务

                //string token = await authenticationService.GetAccessTokenAsync(idc);
                //TokenSave.Token = token;
            }
            #endregion

            #region 密码模式
            {

                //1、配置权限服务信息
                //IdentityClientConfiguration idc = new IdentityClientConfiguration();
                //idc.Authority = "https://localhost:44392";
                //idc.ClientId = "website";
                //idc.ClientSecret = "123456";
                //idc.GrantType = "password"; // 根据用户名和密码授权
                //idc.UserName = "zdf";
                //idc.UserPassword = "Zdf19980525@";
                //idc.Scope = "OrderService"; // 具体访问哪些微服务
                //// 2、创建token
                //string token = authenticationService.GetAccessTokenAsync(idc).Result;

                //// 3、存储token
                //TokenSave.Token = token;

            }
            #endregion

            #region 授权码模式
            {
                var handler = new HttpClientHandler
                {
                    ServerCertificateCustomValidationCallback = HttpClientHandler.DangerousAcceptAnyServerCertificateValidator
                };
                var client = new HttpClient(handler);

                // 获取 discovery document
                var disco = await client.GetDiscoveryDocumentAsync("https://localhost:44392");
                if (disco.IsError) throw new Exception(disco.Error);

                // 使用授权码 + PKCE 获取 AccessToken
                var tokenResponse = await client.RequestAuthorizationCodeTokenAsync(new AuthorizationCodeTokenRequest
                {
                    Address = disco.TokenEndpoint,
                    ClientId = "website",
                    ClientSecret = "123456", // 如果是机密客户端
                    Code = "2ff1ovb9kFsruWpq5OjRsOOfdCT7xDHywBFt5oXATGI",
                    RedirectUri = "http://localhost:4200"
                });

                var refreshResponse = await client.RequestRefreshTokenAsync(new RefreshTokenRequest
                {
                    Address = disco.TokenEndpoint,
                    ClientId = "website",
                    ClientSecret = "123456",
                    RefreshToken = tokenResponse.RefreshToken
                });

                //var revokeResponse = await client.RevokeTokenAsync(new TokenRevocationRequest
                //{
                //    Address = disco.RevocationEndpoint,
                //    ClientId = "website",
                //    ClientSecret = "123456",
                //    Token = refreshResponse.RefreshToken,
                //    TokenTypeHint = "refresh_token"
                //});

            }
            #endregion

            return "创建成功";
        }

        /// <summary>
        /// 自定义
        /// </summary>
        /// <param name="dto"></param>
        /// <returns></returns>
        /// <exception cref="Exception"></exception>
        [HttpPost]
        public async Task<string> CustomeCreateClientToken(CustomeCreateClientTokenDto dto)
        {
            #region 授权码模式

            {
                //var client = new HttpClient();

                //// 获取 discovery document
                //var disco = await client.GetDiscoveryDocumentAsync("https://localhost:44392");
                //if (disco.IsError) throw new Exception(disco.Error);

                //// 使用授权码 + PKCE 获取 AccessToken
                //var tokenResponse = await client.RequestAuthorizationCodeTokenAsync(new AuthorizationCodeTokenRequest
                //{
                //    Address = disco.TokenEndpoint,
                //    ClientId = "website",
                //    ClientSecret = "123456", // 如果是机密客户端
                //    Code = code,
                //    RedirectUri = "http://localhost:4200",
                //});

                //var refreshResponse = await client.RequestRefreshTokenAsync(new RefreshTokenRequest
                //{
                //    Address = disco.TokenEndpoint,
                //    ClientId = "website",
                //    ClientSecret = "123456",
                //    RefreshToken = tokenResponse.RefreshToken
                //});

                ////回收令牌
                ////var revokeResponse = await client.RevokeTokenAsync(new TokenRevocationRequest
                ////{
                ////    Address = disco.RevocationEndpoint,
                ////    ClientId = "website",
                ////    ClientSecret = "123456",
                ////    Token = refreshResponse.RefreshToken,
                ////    TokenTypeHint = "refresh_token"
                ////});
                //TokenSave.Token = tokenResponse.AccessToken;
            }
            #endregion

            #region 密码模式（password）
            {
                var handler = new HttpClientHandler
                {
                    ServerCertificateCustomValidationCallback = HttpClientHandler.DangerousAcceptAnyServerCertificateValidator
                };
                var client = new HttpClient(handler);
                var disco = await client.GetDiscoveryDocumentAsync(_options.Value.Authority);
                if (disco.IsError) throw new Exception(disco.Error);

                var tokenResponse = await client.RequestPasswordTokenAsync(new PasswordTokenRequest
                {
                    Address = disco.TokenEndpoint,
                    ClientId = _options.Value.ClientId,          // 机密客户端需带 ClientSecret
                    ClientSecret = _options.Value.ClientSecret,
                    UserName = dto.UserName,            // 用户名
                    Password = dto.Password,         // 密码
                    Scope = dto.Scope  // 需要的作用域（要刷新令牌则加 offline_access）
                });

                TokenSave.Token = tokenResponse.AccessToken;
            }
            #endregion

            #region 客户端模式（password）
            {
                //var client = new HttpClient();
                //var disco = await client.GetDiscoveryDocumentAsync("https://localhost:44392");
                //if (disco.IsError) throw new Exception(disco.Error);

                //var tokenResponse = await client.RequestClientCredentialsTokenAsync(new ClientCredentialsTokenRequest
                //{
                //    Address = disco.TokenEndpoint,
                //    ClientId = "website",
                //    ClientSecret = "123456",
                //    Scope = "OrderService offline_access"                 // 仅应用自身权限，无用户上下文
                //});

                //TokenSave.Token = tokenResponse.AccessToken;
            }
            #endregion

            #region 返回当前用户的详细信息  (未完成)
            {

            }
            #endregion

            #region 验证令牌的有效性和获取令牌信息  (未完成)
            {

            }
            #endregion

            #region 回收指定的令牌   (未完成)
            {

            }
            #endregion

            return "创建成功" + TokenSave.Token;
        }
    }
}
